home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
INTA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
51KB
|
2,255 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
/* interpreter procedures - interpreter part a */
/* Include standard header modules */
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "int.h"
#include "ivars.h"
#include "farithp.h"
#include "predefp.h"
#include "machinep.h"
#include "taskingp.h"
#include "imiscp.h"
#include "intbp.h"
#include "intcp.h"
#include "intap.h"
static int main_loop();
static int get_word();
#ifdef DEBUG_INT
static void zbreak(int);
#endif
#define TRACE
/* MAIN PROGRAM */
#ifdef DEBUG_STORES
int *heap_store_addr;
/* set heap_store_offset non zero to trace stores to that offset
* in primary heap
*/
extern int heap_store_offset;
int heap_store_now=0;
#endif
int int_main() /*;int_main*/
{
int status;
reset_clock();
num_cunits = 0;
/* Memory initialization, allocate primary heap segment. */
if(!allocate_new_heap()) {
fprintf(stderr,"Unable to allocate primary heap\n");
exit(RC_ABORT);
}
/* Initialize working template for fixed point arithmetic */
*heap_next++ = 1 + WORDS_PTR + WORDS_FX_RANGE;
heap_next += WORDS_PTR;
temp_template = FX_RANGE(heap_next);
temp_template->ttype = TT_FX_RANGE;
temp_template->object_size = 2;
temp_template->small_exp_2 = 0;
temp_template->small_exp_5 = 0;
temp_template->fxlow = MIN_LONG;
temp_template->fxhigh = MAX_LONG;
heap_next += WORDS_FX_RANGE;
/* Other initialization */
sfp = bfp = 0;
initialize_predef();
initialize_tasking();
/* Perform the main loop of the interpretor(terminates at end of pgm) */
status = main_loop();
/* Termination processing */
predef_term();
return status;
}
/*
* MAIN LOOP
* =========
*/
/*
* GET_BYTE Next code byte (char), IP is incremented
* GET_WORD Next code word (int), IP is incremented
* GET_GAD(bse,off) Get base/offset from code, IP incremented
* GET_LAD(bse,off) Get local addr from code, and get corr global addr
*/
#define GET_BYTE (0xff & (int)cur_code[ip++])
#ifdef ALIGN_WORD
#define GET_WORD (w=get_word(), w)
#else
#define GET_WORD (w = *((int *)(cur_code+ip)), ip += sizeof(int), w)
#endif
#define GET_GAD(bse,off) bse=GET_BYTE,off=GET_WORD
#define GET_LAD(bse,off) sp=GET_WORD+sfp,bse=cur_stack[sp],off=cur_stack[sp+1]
static int main_loop() /*;main_loop*/
{
#ifdef DEBUG_INT
int iparg;
#endif
#ifdef ALIGN_WORD
/* auxiliary procedures if must unpack from code stream byte by byte */
#endif
/* General purpose work locations */
/* Loop through instructions */
for (;;) {
#ifdef GWUMON
/* Calculate task timing for each task, one tick is one */
/* pass through the loop */
CWK_TIME_TASK();
#endif
/* Simulate the Clock Interrupt */
if (next_clock_flag &&(next_clock <(now_time = itime() + time_offset)))
clock_interrupt(now_time);
/* Round-robin scheme: next task's turn ? */
if (rr_flag && (rr_counter++ > rr_nb_max_stmts))
round_robin();
#ifdef DEBUG_INT
#ifdef DEBUG_STORES
if (heap_store_offset!=0 &&
heap_store_now != heap_store_addr[heap_store_offset]) {
printf("heap stores change %d from %d to %d\n",
heap_store_offset, heap_store_now,
heap_store_addr[heap_store_offset]);
heap_store_now = heap_store_addr[heap_store_offset];
}
#endif
iparg = ip;
if (instruction_trace)
i_list1(&iparg, cur_code); /* debug */
if(break_point && (ip >= break_point))
zbreak(0);
#endif
/* Get next opcode, bump instruction pointer and switch to routine */
switch(GET_BYTE) {
case I_NOP:
break;
/* Instructions Dealing with Tasking */
case I_ABORT:
value = GET_WORD; /* number of tasks in stack */
abort(value);
break;
case I_ACTIVATE:
if (BLOCK_FRAME->bf_tasks_declared != 0) {
value = pop_task_frame();
start_activation(value, tp, bfp);
/* master is current block frame */
}
break;
case I_ACTIVATE_NEW_L:
GET_LAD(bse, off);
if (BLOCK_FRAME->bf_tasks_declared != 0) {
value = pop_task_frame();
ptr = ADDR(bse, off);
start_activation(value, ACCESS(ptr)->master_task,
ACCESS(ptr)->master_bfp);
}
break;
case I_ACTIVATE_NEW_G:
GET_GAD(bse, off);
if (BLOCK_FRAME->bf_tasks_declared != 0) {
value = pop_task_frame();
ptr = ADDR(bse, off);
start_activation(value, ACCESS(ptr)->master_task,
ACCESS(ptr)->master_bfp);
}
break;
case I_CREATE_TASK_G:
GET_GAD(bse, off);
start_creation(bse, off);
break;
case I_CREATE_TASK_L:
GET_LAD(bse, off);
start_creation(bse, off);
break;
case I_POP_TASKS_DECLARED_G:
GET_GAD(bse, off);
if (BLOCK_FRAME->bf_tasks_declared != 0)
value = pop_task_frame();
else
value = 0;
*ADDR(bse, off) = value;
break;
case I_POP_TASKS_DECLARED_L:
GET_LAD(bse, off);
if (BLOCK_FRAME->bf_tasks_declared != 0)
value = pop_task_frame();
else
value = 0;
*ADDR(bse, off) = value;
break;
case I_LINK_TASKS_DECLARED:
POP(value);
push_task_frame(value);
break;
case I_CURRENT_TASK:
PUSH(tp);
break;
case I_END_ACTIVATION:
value = GET_BYTE;
end_activation(value); /* 0=error during activation, 1=ok */
break;
case I_END_RENDEZVOUS:
end_rendezvous();
break;
case I_ENTRY_CALL:
value = GET_WORD; /* retrieve parameter from code */
entry_call((long) ENDLESS,value);
break;
case I_RAISE_IN_CALLER:
raise_in_caller();
break;
case I_SELECTIVE_WAIT:
value = GET_WORD; /* number of alternatives */
/* if = 0 then it is a simple accept, entry addr is on stack. */
/* else: alternative descriptors on to of stack are scanned by */
/* the procedure, which leaves the index of the chosen one. */
selective_wait(value);
break;
case I_TERMINATE:
purge_rdv(tp);
value = GET_BYTE;
deallocate(BLOCK_FRAME->bf_data_link);
/* bf_tasks_declared always null here */
switch(value) {
case 0: /* task terminates because reaches the end */
break;
case 1: /* task terminates because of terminate alternative */
break;
case 2:
value = 0;
#ifdef GWUMON
{
char msg[240];
sprintf(msg,"task %d terminated due to unhandled exception: %s\n"
,tp,exception_slots[exr]);
CWK_Exception_Raised( tp, msg );
}
#else
if (exception_trace)
printf("task %d terminated due to unhandled exception: %s\n"
,tp,exception_slots[exr]);
#endif
break;
case 3:
printf("unhandled exception in library unit %s\n",
exception_slots[exr]);
return RC_ERRORS;
case 4:
printf("main task terminated due to unhandled exception %s\n",
exception_slots[exr]);
printf("propagated from %s",code_slots[raise_cs]);
if (raise_lin) printf(" at line %d",raise_lin);
printf(" (%s)\n",raise_reason);
return RC_ERRORS;
case 5: /* normal end of main */
return RC_SUCCESS;
case 6: /* dead-lock */
printf("dead-lock: system inactive\n");
return RC_ERRORS;
}
complete_task();
break;
case I_TIMED_ENTRY_CALL:
POPL(lvalue);
/* retrieve length of parameter table from code */
entry_call((lvalue >= 0) ? lvalue : (long) 0, GET_WORD);
break;
case I_WAIT: /* delay */
POPL(lvalue);
delay_stmt(lvalue);
break;
/* Instructions for Memory Allocation */
case I_CREATE_B:
case I_CREATE_W:
create(1, &bse, &off, &ptr);
PUSH_ADDR(bse, off);
break;
case I_CREATE_L:
create(WORDS_LONG, &bse, &off, &ptr);
PUSH_ADDR(bse, off);
break;
case I_CREATE_A:
create(2, &bse, &off, &ptr);
PUSH_ADDR(bse, off);
break;
case I_CREATE_STRUC:
create_structure();
break;
case I_CREATE_COPY_STRUC:
creat